import exceptions.RetryException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.concurrent.*;

/**
 * Created by shuoGG on 2018/8/3
 */
public class RetryUtil {
    private static final Log logger = LogFactory.getLog(RetryUtil.class);

    private static ThreadPoolExecutor threadPool = new ThreadPoolExecutor(4, 50, 60, TimeUnit.SECONDS, new ArrayBlockingQueue(3));

    /**
     * 任务超时+重试封装
     *
     * @param task       异步任务
     * @param retry      重试次数
     * @param perTimeout 每次的
     * @return
     * @throws RetryException 重试失败
     */
    public static Object tryN(Callable<Object> task, int retry, int perTimeout) throws RetryException {
        int time = retry;
        while (0 < time--) {
            Future f = threadPool.submit(task);
            try {
                return f.get(perTimeout, TimeUnit.SECONDS);
            } catch (InterruptedException | ExecutionException e) {
                logger.error("其他异常, 正在重试", e);
            } catch (TimeoutException e) {
                logger.error("超时, 正在重试", e);
            }
        }
        throw new RetryException("经过" + retry + "次重试依旧失败, 放弃");
    }

    public static void tryN(Runnable task, int retry, int perTimeout) throws RetryException {
        int time = retry;
        while (0 < time--) {
            Future f = threadPool.submit(task);
            try {
                f.get(perTimeout, TimeUnit.SECONDS);
                return;
            } catch (InterruptedException | ExecutionException e) {
                logger.error("其他异常, 正在重试", e);
            } catch (TimeoutException e) {
                logger.error("超时, 正在重试", e);
            }
        }
        throw new RetryException("经过" + retry + "次重试依旧失败, 放弃");
    }

}
